// --------------------------------------------------------------------------------------------------------------------
// <copyright file="FormsAuthenticationService.cs" company="">
//   
// </copyright>
// <summary>
//   Authentication service
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Skymate.Services.Authentication
{
    using System;
    using System.Web;
    using System.Web.Security;

    /// <summary>
    ///     Authentication service
    /// </summary>
    public class FormsAuthenticationService : IAuthenticationService
    {
        /*private readonly ICustomerService _customerService;
        private readonly CustomerSettings _customerSettings;*/

        /// <summary>
        ///     The _expiration time span.
        /// </summary>
        private readonly TimeSpan _expirationTimeSpan;

        /// <summary>
        ///     The _http context.
        /// </summary>
        private readonly HttpContextBase _httpContext;

        /// <summary>
        ///     The _cached customer.
        /// </summary>
        private string _cachedCustomer;

        /// <summary>
        /// Initializes a new instance of the <see cref="FormsAuthenticationService"/> class.
        ///     Ctor
        /// </summary>
        /// <param name="httpContext">
        /// HTTP context
        /// </param>
        public FormsAuthenticationService(HttpContextBase httpContext /*,
            ICustomerService customerService, CustomerSettings customerSettings*/)
        {
            this._httpContext = httpContext;

            /*this._customerService = customerService;
            this._customerSettings = customerSettings;*/
            this._expirationTimeSpan = FormsAuthentication.Timeout;
        }

        /// <summary>
        /// The sign in.
        /// </summary>
        /// <param name="customer">
        /// The customer.
        /// </param>
        /// <param name="createPersistentCookie">
        /// The create persistent cookie.
        /// </param>
        public virtual void SignIn(string customer, bool createPersistentCookie)
        {
            var now = DateTime.UtcNow.ToLocalTime();

            var ticket = new FormsAuthenticationTicket(
                1 /*version*/, 
                customer /*_customerSettings.UsernamesEnabled ? customer.Username : customer.Email*/, 
                now, 
                now.Add(this._expirationTimeSpan), 
                createPersistentCookie, 
                customer /*_customerSettings.UsernamesEnabled ? customer.Username : customer.Email*/, 
                FormsAuthentication.FormsCookiePath);

            var encryptedTicket = FormsAuthentication.Encrypt(ticket);

            var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
            cookie.HttpOnly = true;
            if (ticket.IsPersistent)
            {
                cookie.Expires = ticket.Expiration;
            }

            cookie.Secure = FormsAuthentication.RequireSSL;
            cookie.Path = FormsAuthentication.FormsCookiePath;
            if (FormsAuthentication.CookieDomain != null)
            {
                cookie.Domain = FormsAuthentication.CookieDomain;
            }

            this._httpContext.Response.Cookies.Add(cookie);

            this._cachedCustomer = customer;
        }

        /// <summary>
        ///     The sign out.
        /// </summary>
        public virtual void SignOut()
        {
            this._cachedCustomer = null;
            FormsAuthentication.SignOut();
        }

        /// <summary>
        ///     The get authenticated customer.
        /// </summary>
        /// <returns>
        ///     The <see cref="string" />.
        /// </returns>
        public virtual string GetAuthenticatedCustomer()
        {
            if (this._cachedCustomer != null)
            {
                return this._cachedCustomer;
            }

            if (this._httpContext == null || this._httpContext.Request == null
                || !this._httpContext.Request.IsAuthenticated || !(this._httpContext.User.Identity is FormsIdentity))
            {
                return null;
            }

            var formsIdentity = (FormsIdentity)this._httpContext.User.Identity;
            var customer = this.GetAuthenticatedCustomerFromTicket(formsIdentity.Ticket);
            if (!string.IsNullOrEmpty(customer))
            {
                this._cachedCustomer = customer;
            }

            /*if (customer != null && customer.Active && !customer.Deleted && customer.IsRegistered())
                _cachedCustomer = customer;*/
            return this._cachedCustomer;
        }

        /// <summary>
        /// The get authenticated customer from ticket.
        /// </summary>
        /// <param name="ticket">
        /// The ticket.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public virtual string GetAuthenticatedCustomerFromTicket(FormsAuthenticationTicket ticket)
        {
            Guard.ArgumentNotNull(ticket, "ticket");

            var usernameOrEmail = ticket.UserData;

            if (string.IsNullOrWhiteSpace(usernameOrEmail))
            {
                return null;
            }

            var customer = usernameOrEmail;

            return customer;
        }
    }
}